93장. IaC — CloudFormation · Terraform 개요
이 장에서 말하고자 하는 것
지금까지 우리는 콘솔과 CLI로 자원을 만들었다.
운영을 진지하게 하려면 다음 질문이 생긴다.
- 같은 환경을 dev/stage/prod 에 똑같이 만들 수 있나?
- 누가 무엇을 바꿨는지 코드처럼 리뷰할 수 있나?
- 어제와 오늘의 인프라 차이를 볼 수 있나?
이 모든 답이
Infrastructure as Code (IaC)
다.
AWS 환경의 두 가지 주류:
- AWS CloudFormation — AWS 자체
- Terraform — HashiCorp · 멀티 클라우드
1. CloudFormation — AWS 네이티브
- YAML / JSON으로 자원 선언
- AWS가 관리하는 Stack 단위로 배포 / 롤백
- AWS 서비스 변경에 가장 빠르게 따라옴
- AWS만 다룬다
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: msa-prod-uploads
- CDK (TypeScript · Python · Go 등 코드) 도 결국 CloudFormation으로 변환된다
2. Terraform — 멀티 클라우드 표준
- HCL (HashiCorp Configuration Language)
- AWS · GCP · Azure · GitHub · Datadog 등 거의 모든 시스템 지원
- Plan / Apply 워크플로우가 명확
- State 파일로 현재 상태 추적
resource "aws_s3_bucket" "uploads" {
bucket = "msa-prod-uploads"
}
- 사실상 IaC의 업계 표준
- AWS 외 서비스도 같은 도구로 관리
새 프로젝트는 Terraform이 사실상 기본 — 멀티 클라우드 / 외부 서비스 통합이 자연스럽다
3. 두 도구 비교
| 항목 | CloudFormation | Terraform |
|---|---|---|
| 범위 | AWS 전용 | 멀티 클라우드 |
| 언어 | YAML/JSON (+ CDK 코드) | HCL |
| State | AWS가 관리 | 본인이 관리 (S3 + DynamoDB) |
| 새 AWS 서비스 지원 | 가장 빠름 | 약간 늦음 (provider 업데이트) |
| 도입 비용 | 낮음 | 약간 높음 |
| 생태계 | 작음 | 매우 큼 |
4. IaC가 풀어주는 문제들
1. 환경 복제
dev / stage / prod 를 같은 코드로 만든다.
2. 변경 리뷰
Terraform Plan / CloudFormation ChangeSet 으로 “무엇이 바뀌는지” 사전에 본다.
Pull Request로 리뷰 가능.
3. 롤백
이전 커밋으로 돌아가면 인프라도 함께 돌아간다.
4. 문서화
코드가 곧 운영 문서다 — “왜 이 보안 그룹이 있나” 가 커밋 메시지에 있다.
5. 자동화의 토대
CI/CD가 인프라까지 함께 다룰 수 있다.
5. State — Terraform의 핵심 개념
terraform.tfstate
├─ 어떤 자원이 만들어졌나
├─ 자원의 현재 속성값
└─ 자원 간 의존 관계
State 파일은 민감한 정보를 담을 수 있다 (RDS 비밀번호 등).
S3 (암호화) + DynamoDB (잠금) 조합으로 원격 State 운영이 표준
terraform {
backend "s3" {
bucket = "msa-tfstate"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "msa-tfstate-lock"
}
}
6. 모듈화 — 같은 패턴 반복
orders · users · payments 같은 마이크로서비스가 모두 비슷한 모양이라면 모듈 로 묶는다.
module "orders" {
source = "./modules/microservice"
name = "orders"
port = 8080
}
module "users" {
source = "./modules/microservice"
name = "users"
port = 8081
}
새 서비스를 추가할 때 모듈 호출 한 블록만 추가하면 끝.
7. Workflow — Plan · Apply
1. 코드 작성 / 수정
2. terraform plan → 무엇이 바뀔지 미리 본다
3. PR로 리뷰
4. 머지 후 terraform apply (CI에서 자동)
- Plan 결과를 PR에 자동 코멘트 (Atlantis · Terraform Cloud · GitHub Actions)
- Apply는 사람의 명시적 승인 후 (또는 자동, 신중히)
8. 우리 서비스에서
terraform/
├─ providers.tf (aws, version)
├─ backend.tf (remote state)
├─ network/ (VPC · 서브넷 · 라우팅 · Endpoint)
├─ shared/ (ALB · CloudFront · WAF)
├─ services/
│ ├─ orders/ (ECS Service · Task Def · RDS)
│ ├─ users/
│ └─ payments/
└─ environments/
├─ dev.tfvars
├─ stage.tfvars
└─ prod.tfvars
- 같은 코드 + 환경별 변수
- 환경별 별도 State (서로 독립)
9. 직접 확인해보기 — CLI
# 초기화 (provider 다운로드 · backend 연결)
terraform init
# 무엇이 바뀔지 미리 보기
terraform plan -var-file=environments/prod.tfvars
# 적용
terraform apply -var-file=environments/prod.tfvars
# 자원 삭제 (위험!)
terraform destroy -var-file=environments/prod.tfvars
plan 의 출력을 읽는 능력이 IaC 운영의 핵심 스킬이다.
10. 코드로는 이렇게 생겼다 — Terraform 모듈 호출
module "vpc" {
source = "./modules/vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-2a", "ap-northeast-2c"]
}
module "orders_service" {
source = "./modules/microservice"
name = "orders"
vpc_id = module.vpc.id
subnets = module.vpc.private_subnets
alb_listener = module.shared.alb_listener
container_image = "${var.ecr_url}/orders:${var.image_tag}"
db_engine = "postgres"
db_instance_class = "db.t4g.small"
}
같은 모듈을 여러 서비스에 인스턴스화 — 운영의 표준.
11. 이렇게 쓰면 망한다 — 안티패턴
안티패턴 1. 콘솔로 만든 자원과 IaC가 섞인다
“실제 운영 자원” 이 어디서 만들어졌는지 추적이 안 된다.
한 자원은 한 방식으로만 관리
안티패턴 2. State 파일을 Git에 커밋
민감한 정보(비밀번호 · ARN)가 평문으로 저장소에 남는다.
원격 State (S3 + KMS) 가 표준
안티패턴 3. Apply 권한을 누구나 가진다
실수 한 번에 운영 자원이 사라진다.
CI/CD를 통한 Apply, 사람은 PR 리뷰만
안티패턴 4. 한 State 파일에 모든 환경
prod와 dev가 같은 파일에 있으면 잘못된 변경이 prod에 영향.
환경마다 별도 State
12. 한 줄로 정리
IaC는 인프라를 코드로 다루는 패러다임이며,
새 프로젝트는 Terraform이 사실상 기본 — Plan · 모듈 · 원격 State 가 운영의 토대다
13. 이 장의 핵심 정리
- IaC는 환경 복제 · 변경 리뷰 · 롤백 · 자동화의 토대다.
- CloudFormation은 AWS 네이티브, Terraform은 멀티 클라우드 표준이다.
- Terraform은 State + Plan/Apply 워크플로우가 핵심이다.
- 원격 State (S3 + DynamoDB) 가 사실상 표준.
- 모듈로 같은 패턴을 반복한다.
- Apply 권한은 CI/CD로 한정, 사람은 PR 리뷰.